﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Text.RegularExpressions;
using System.Management;
using System.Diagnostics;

namespace HyperVGuestToolbox
{
    public enum Tabs { ChangeDVD, Settings, Help, About }

    public partial class Main : Form
    {
        public void SetTab(Tabs tab)
        {
            string tabName ="";
            switch (tab)
            {
                case Tabs.About:
                    tabName = "tabAbout";
                    break;
                case Tabs.ChangeDVD :
                    tabName = "tabGuestSettings";
                    break;
                case Tabs.Help :
                    tabName = "tabHelp";
                    break;
                case Tabs.Settings:
                    tabName = "tabSettings";
                    break;

            }
            this.tabAllSettings.SelectedTab = this.tabAllSettings.TabPages [tabName];
            
        }

        public Main()
        {
            InitializeComponent();
            this.FormClosing += new FormClosingEventHandler(Main_FormClosing);
            
            numRecentUsedLimit.Value = Convert.ToDecimal (Program.AppSettings.HistoryCount ) ;
            txtExtensions.Text = Program.AppSettings.Extensions;
            txtSearchFolders.Text = string.Join("\n",Program.AppSettings.SearchFolders);
            chkSearchSubDirectories.Checked = Program.AppSettings.SearchSubDirectories;
            txtVirtualHost.Text  = Program.AppSettings.VirtualHost;
            txtVirtualGuest.Text  = Program.AppSettings.VirtualGuest;
            DisplayCurrentDVD();
        }

        private void DisplayCurrentDVD()
        {
            if (String.IsNullOrEmpty (Program.AppSettings.CurrentImage))
            {
                txtCurrentFilename.Text = "---No Imaged Inserted ---";
                txtCurrentPath.Text ="";
                btnEject.Visible = false;

            }
            else
            {
            txtCurrentFilename.Text = Path.GetFileName(Program.AppSettings.CurrentImage);
            txtCurrentPath.Text = Path.GetDirectoryName(Program.AppSettings.CurrentImage);
            btnEject.Visible  = false;
            }
        }

        void Main_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing && !bCanExit )
            {
                Save();
                this.Hide();
                this.ShowInTaskbar = false;

                e.Cancel = true;
            }
        }

        public void Save()
        {

            Program.AppSettings.SaveSettings(Convert.ToInt32(numRecentUsedLimit.Value)
                                            , txtExtensions.Text
                                            , txtSearchFolders.Text.Trim()
                                            , chkSearchSubDirectories.Checked
                                            , txtVirtualGuest.Text
                                            , txtVirtualHost.Text);

        }

        private void txtSearchFolders_TextChanged(object sender, EventArgs e)
        {
            ValidateSearchFolders();
        }

        private void ValidateSearchFolders()
        {
            int curSelectionLength = txtSearchFolders.SelectionLength ;
            int curSelectionStart = txtSearchFolders.SelectionStart  ;
            //txtSearchFolders.SelectionType =  RichTextBoxSelectionTypes.  ;
            
            //txtSearchFolders.SelectionColor = 
            var Errors = new StringBuilder();
            Regex SplitFolders = new Regex("^(.*)$", RegexOptions.Multiline  );

            var SearchFolders = SplitFolders.Matches (txtSearchFolders.Text.Trim() );
            for (int i = 0; i < SearchFolders.Count ; i++)
            {
                var Folder = SearchFolders[i];
                var ItemColor = Color.Black;
                if (!Directory.Exists(Folder.Value ))
                {
                    Errors.AppendLine(string.Format("Folder on line {0} can't be found", i + 1));
                    ItemColor = Color.Red;
                }
                  txtSearchFolders.SelectionStart=Folder.Index ;
                txtSearchFolders.SelectionLength = Folder.Length ;
                txtSearchFolders.SelectionColor = ItemColor;

            }
            rtfErrors.Text = Errors.ToString ();
             txtSearchFolders.SelectionStart=curSelectionStart ;
            txtSearchFolders.SelectionLength = curSelectionLength;
        }

        private void tabAllSettings_SelectedIndexChanged(object sender, EventArgs e)
        {
            Save();

            switch ((Tabs)tabAllSettings.SelectedIndex)
            {
                case Tabs.ChangeDVD :
                    CheckForCurrentImage();

                    LoadFileGrid();
                    break;
            }
        }

        private void CheckForCurrentImage()
        {
            //Connect to the Virtual Server and find the current image


        
            //ManagementObject mo = new ManagementObject(oMs,@"\root\virtualization\Msvm_ComputerSystem",ObjectGetOptions.InfiniteTimeout);
            
        }

        private void LoadFileGrid()
        {

            string FileBeforeLoad = CurrentFile();
            var Images = from dvd in Program.AppSettings.DVDFiles
                         where string.IsNullOrEmpty(txtFilterText.Text) | dvd.Key.Contains(txtFilterText.Text)
                         select dvd.Value;

            var ColSort = new Dictionary<string, SortOrder>();
            foreach (DataGridViewColumn Col in grdMatchedFiles.Columns)
            {
                ColSort.Add(Col.Name, Col.HeaderCell.SortGlyphDirection);
                switch (Col.HeaderCell.SortGlyphDirection)
                {
                    case SortOrder.Ascending:
                        if (Col.DataPropertyName == "Filename")
                            Images = Images.OrderBy(dvd => dvd.filename);
                        else if (Col.DataPropertyName == "Folder")
                            Images = Images.OrderBy(dvd => dvd.folder);
                        else if (Col.DataPropertyName == "History")
                            Images = Images.OrderBy(dvd => !dvd.History.HasValue?int.MaxValue:dvd.History  );
                        break;
                    case SortOrder.Descending:
                        if (Col.DataPropertyName == "Filename")
                            Images = Images.OrderByDescending(dvd => dvd.filename);
                        else if (Col.DataPropertyName == "Folder")
                            Images = Images.OrderByDescending(dvd => dvd.folder);
                        else if (Col.DataPropertyName == "History")
                            Images = Images.OrderByDescending(dvd => dvd.History);
                        break;
                }
            }

            grdMatchedFiles.DataSource = Images.ToList();
            foreach (var col in ColSort)
            {
                grdMatchedFiles.Columns[col.Key].HeaderCell.SortGlyphDirection = col.Value;
            }
            if (!String.IsNullOrEmpty(FileBeforeLoad))
            {
                foreach (DataGridViewRow item in grdMatchedFiles.Rows)
                {
                    if (GetFilenameFromRow(item) == FileBeforeLoad)
                        item.Selected = true;
                }
            }
        }

        private void txtFilterText_TextChanged(object sender, EventArgs e)
        {
            LoadFileGrid();
        }

        private void grdMatchedFiles_SelectionChanged(object sender, EventArgs e)
        {
            txtFullPath.Text =CurrentFile();
        }

        private string CurrentFile()
        {
            if (grdMatchedFiles.SelectedRows.Count > 0)
            {
                var selectedRow = grdMatchedFiles.SelectedRows[0];
                return GetFilenameFromRow(selectedRow);
            }
            else return "";
        }

        private static string GetFilenameFromRow(DataGridViewRow selectedRow)
        {
            var selectedDVD = (DVDFile)selectedRow.DataBoundItem;
            return selectedDVD.fullpath;
        }

        private void btnInsert_Click(object sender, EventArgs e)
        {
            var CursorAtStart = this.Cursor;
            this.Cursor = Cursors.WaitCursor;
            if (String.IsNullOrEmpty(txtFullPath.Text))
            {
                MessageBox.Show("No image file selected");
                return;
            }
            if (String.IsNullOrEmpty(txtFullPath.Text))
            {
                MessageBox.Show("File doesn't exist or you don't have permission to it. Please select another file");
                return;
            }
            //TODO: Insert DVD into the machine
            Program.AppSettings.InsertImage(txtFullPath.Text);
            //TODO: Record the history

            Program.AppSettings.AddToHistory(txtFullPath.Text);

            LoadFileGrid();
            DisplayCurrentDVD();
            this.Cursor = CursorAtStart;
        }

        private void grdMatchedFiles_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            var CurrentOrder = grdMatchedFiles.Columns[e.ColumnIndex].HeaderCell.SortGlyphDirection;
            switch (CurrentOrder)
            {
                case SortOrder.Ascending:
                    CurrentOrder = SortOrder.Descending;
                    break;
                case SortOrder.Descending :
                    CurrentOrder = SortOrder.None;
                    break;
                case SortOrder.None:
                    CurrentOrder = SortOrder.Ascending ;
                    break;

            }
            grdMatchedFiles.Columns[e.ColumnIndex].HeaderCell.SortGlyphDirection =CurrentOrder ;

            LoadFileGrid();
            //DataGridViewColumnHeaderCell.SortGlyphDirection 
            //  grdMatchedFiles.Sort(grdMatchedFiles.Columns[e.ColumnIndex], ListSortDirection.Ascending);
        }

        private void btnBrowseForCDFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog fd = new OpenFileDialog();

            fd.CheckFileExists = true;
            fd.CheckPathExists = true;
            fd.Title = "Select an iso file";
            fd.Filter = Program.AppSettings.Extensions +"|"+ Program.AppSettings.Extensions.Replace(",",";");// string.Join("|", (from s in Program.AppSettings.Extensions.Split(',')
                                                         //                 select s + "|" + s));
            if (fd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                txtFullPath.Text = fd.FileName;
                
            }

        }

        private void btnEject_Click(object sender, EventArgs e)
        {
            Program.AppSettings.InsertImage("");
            DisplayCurrentDVD();

        }


        private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ShowSpecifcTab(Tabs.Settings);
        }

        bool bCanExit = false;

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            bCanExit = true;
            this.Close ();
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ShowSpecifcTab(Tabs.About);
        }

        private void ShowSpecifcTab(Tabs tabToShow)
        {

            this.SetTab(tabToShow);
            this.ShowInTaskbar = true;
            this.Show();
            
        }

        private void helpToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ShowSpecifcTab(Tabs.Help);
        }

        private void changeCDToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ShowSpecifcTab(Tabs.ChangeDVD );
        }

        private void tabGuestSettings_Click(object sender, EventArgs e)
        {

        }

        private void Main_Load(object sender, EventArgs e)
        {
            //this.WindowState = FormWindowState.Minimized;
            LoadFileGrid();
            helpBrowser.Navigate ( Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "Help.htm"));
            helpBrowser.Navigating += new WebBrowserNavigatingEventHandler(helpBrowser_Navigating);
        }

        void helpBrowser_Navigating(object sender, WebBrowserNavigatingEventArgs e)
        {
            Process.Start(e.Url.AbsoluteUri);

            e.Cancel = true;
        }

        private void richTextBox3_TextChanged(object sender, EventArgs e)
        {

        }

        private void richTextBox3_LinkClicked(object sender, LinkClickedEventArgs e)
        {

        }

        private void sysTrayNotify_MouseDoubleClick(object sender, MouseEventArgs e)
        {

        }

        private void sysTrayNotify_MouseClick(object sender, MouseEventArgs e)
        {
            ShowSpecifcTab(Tabs.ChangeDVD);
        }

    
    }
}
